package com.pucong.gitee.database.backup.business.database.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pucong.gitee.database.backup.business.database.mapper.BackupDatabaseMapper;
import com.pucong.gitee.database.backup.business.database.mapper.BackupExeSqlLogMapper;
import com.pucong.gitee.database.backup.business.database.util.BackupServiceFactory;
import com.pucong.gitee.database.backup.business.database.util.OperationService;
import com.pucong.gitee.database.backup.business.database.vo.DbBackTree;
import com.pucong.gitee.database.backup.business.database.vo.DeleteDatabase;
import com.pucong.gitee.database.backup.business.database.vo.ExeSqlResult;
import com.pucong.gitee.database.backup.business.database.vo.RenameDatabase;
import com.pucong.gitee.database.backup.business.service.mapper.ServiceComputerMapper;
import com.pucong.gitee.database.backup.business.service.mapper.ServiceFileMapper;
import com.pucong.gitee.database.backup.business.sys.mapper.SysUserInfoMapper;
import com.pucong.gitee.database.backup.business.sys.service.SysUserInfoService;
import com.pucong.gitee.database.backup.common.entity.database.BackupDatabase;
import com.pucong.gitee.database.backup.common.entity.service.ServiceComputer;
import com.pucong.gitee.database.backup.common.entity.service.ServiceFile;
import com.pucong.gitee.database.backup.common.entity.sys.UserJwt;
import com.pucong.gitee.database.backup.common.selfenum.ServiceFileType;
import com.pucong.gitee.database.backup.common.selfenum.ServiceType;
import com.pucong.gitee.database.backup.common.selfenum.TreeType;
import com.pucong.gitee.database.backup.configuration.exception.BusinessException;
import com.pucong.gitee.database.backup.utils.UUID;
import com.pucong.gitee.database.backup.utils.UserRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 人员表 service实现类
 *
 * @author pucong
 * @url https://gitee.com/pucong
 * @create 2020-06-23
 */
@Service
public class BackupDatabaseServiceImpl implements BackupDatabaseService {

    @Autowired
    private BackupDatabaseMapper backupDatabaseMapper;

    @Autowired
    private DatabaseStaticService databaseStaticService;

    @Autowired
    private BackupExeSqlLogMapper backupExeSqlLogMapper;

    @Autowired
    private ServiceComputerMapper serviceComputerMapper;

    @Autowired
    private SysUserInfoMapper sysUserInfoMapper;

    @Autowired
    private SysUserInfoService sysUserInfoService;

    @Autowired
    private ServiceFileMapper serviceFileMapper;

    @Override
    public IPage<BackupDatabase> getDatabaseListByPage(int pageNum, int pageSize, BackupDatabase backupDatabase) {
        Page<BackupDatabase> page = new Page<>(pageNum, pageSize);
        List<String> userIds = sysUserInfoService.selectChildrenUserId();
        if(userIds.size() == 0){
            return page;
        }
        //构造分页查询
        LambdaQueryWrapper<BackupDatabase> params = new LambdaQueryWrapper<>();
        params.eq(StringUtils.isNotBlank(backupDatabase.getConnectName()),BackupDatabase::getConnectName,backupDatabase.getConnectName())
                .eq(StringUtils.isNotBlank(backupDatabase.getDatabaseName()),BackupDatabase::getDatabaseName,backupDatabase.getDatabaseName())
                .in(userIds != null ,BackupDatabase::getCreateBy,userIds);

        params.orderByDesc(BackupDatabase::getCreateTime);
        IPage<BackupDatabase> backupDatabaseIPage = backupDatabaseMapper.selectPage(page, params);
        return backupDatabaseIPage;
    }

    @Override
    public List<BackupDatabase> getDatabaseList() {
        List<String> userIds = sysUserInfoService.selectChildrenUserId();
        if(userIds.size() == 0){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<BackupDatabase> params = new LambdaQueryWrapper<>();
        params.in(userIds != null ,BackupDatabase::getCreateBy,userIds);
        List<BackupDatabase> backupDatabases = backupDatabaseMapper.selectList(params);
        return backupDatabases;
    }

    @Override
    public BackupDatabase getBaseInfoById(String id) {
        return backupDatabaseMapper.selectById(id);
    }

    @Override
    public int saveBaseInfo(BackupDatabase backupDatabase) {
        if(StringUtils.isBlank(backupDatabase.getUuid())){
            UserJwt loginUser = UserRequest.getLoginUser();
            backupDatabase.setUuid(UUID.uuid());
            backupDatabase.setCreateTime(new Date());
            backupDatabase.setCreateBy(loginUser.getUuid());
            backupDatabaseMapper.insert(backupDatabase);
        }else{
            backupDatabase.setCreateTime(null);
            backupDatabase.setCreateBy(null);
            backupDatabaseMapper.updateById(backupDatabase);
        }
        return 1;
    }

    @Override
    public boolean connectionTest(BackupDatabase backupDatabase) {
        BackupServiceFactory backupServiceFactory = new BackupServiceFactory();
        OperationService operationService = backupServiceFactory.getBackupService(backupDatabase,backupExeSqlLogMapper);
        Boolean connection = operationService.getConnection();
        operationService.closeAll();
        return connection;
    }

    @Override
    public boolean connectionTestById(String id) {
        BackupDatabase backupDatabase = backupDatabaseMapper.selectById(id);
        if(backupDatabase == null){
            throw new BusinessException("获取数据库异常，未找到数据");
        }
        BackupServiceFactory backupServiceFactory = new BackupServiceFactory();
        OperationService operationService = backupServiceFactory.getBackupService(backupDatabase,backupExeSqlLogMapper);
        Boolean connection = operationService.getConnection();
        operationService.closeAll();
        return connection;
    }

    @Override
    public ExeSqlResult getDatabaseList(String databaseId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String sessionId = request.getSession().getId();
        OperationService operationService = databaseStaticService.getConnectionById(sessionId, databaseId);
        ExeSqlResult dataBaseList = operationService.getDataBaseList();
        operationService.closeAll();
        return dataBaseList;
    }

    @Override
    public Boolean closeConnection(String databaseId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String sessionId = request.getSession().getId();
        OperationService operationService = databaseStaticService.getConnectionById(sessionId, databaseId);
        operationService.closeAll();
        return true;
    }

    @Override
    public Boolean renameDatabase(String databaseId, RenameDatabase renameDatabase) {
        OperationService operationService = databaseStaticService.getConnectionById(renameDatabase.getSessionId(), databaseId);
        operationService.renameDatabase(renameDatabase.getDatabaseName(),renameDatabase.getToDatabaseName());
        operationService.closeAll();
        return true;
    }

    @Override
    public Boolean deleteDatabase(String databaseId, DeleteDatabase deleteDatabase) {
        OperationService operationService = databaseStaticService.getConnectionById(deleteDatabase.getSessionId(), databaseId);
        operationService.dropDatabase(deleteDatabase.getDatabaseName());
        operationService.closeAll();
        return true;
    }

    @Override
    public List<DbBackTree> getTreeList(String id, TreeType treeType) {
        UserJwt loginUser = UserRequest.getLoginUser();
        List<DbBackTree> dbBackTrees = new ArrayList<>();
        if(StringUtils.isNotBlank(id)){
            switch (treeType) {
                case 数据源:
                    // 获取数据源下的数据库

                    break;
                case 数据库:
                    // 获取数据库下的模式

                    break;
            }
            return dbBackTrees;
        }else{
            /**
             * 查询一级列表
             * 权限查询
             */
            List<String> ids = sysUserInfoService.selectChildrenUserId();
            // 数据源
            LambdaQueryWrapper<BackupDatabase> backupDatabaseParams = new LambdaQueryWrapper<>();
            backupDatabaseParams.in(ids != null ,BackupDatabase::getUuid,ids);
            List<BackupDatabase> backupDatabases = backupDatabaseMapper.selectList(backupDatabaseParams);
            // 服务器
            LambdaQueryWrapper<ServiceComputer> serviceComputerParams = new LambdaQueryWrapper<>();
            serviceComputerParams.in(ids != null ,ServiceComputer::getUuid,ids);
            List<ServiceComputer> serviceComputers = serviceComputerMapper.selectList(serviceComputerParams);
            // 文件服务器
            LambdaQueryWrapper<ServiceFile> serviceFileParams = new LambdaQueryWrapper<>();
            serviceFileParams.in(ids != null ,ServiceFile::getUuid,ids);
            List<ServiceFile> serviceFiles = serviceFileMapper.selectList(serviceFileParams);
            for (BackupDatabase backupDatabase : backupDatabases) {
                DbBackTree dbBackTree = new DbBackTree();
                dbBackTree.setId(backupDatabase.getUuid());
                dbBackTree.setPId("0");
                dbBackTree.setTreeName(backupDatabase.getConnectName());
                dbBackTree.setTreeType(TreeType.数据源);
                dbBackTrees.add(dbBackTree);
            }
            for (ServiceComputer serviceComputer : serviceComputers) {
                DbBackTree dbBackTree = new DbBackTree();
                dbBackTree.setId(serviceComputer.getUuid());
                dbBackTree.setPId("0");
                dbBackTree.setTreeName(serviceComputer.getServiceName());
                if(ServiceType.linux == serviceComputer.getServiceType()){
                    dbBackTree.setTreeType(TreeType.linux服务器);
                }else{
                    dbBackTree.setTreeType(TreeType.Windows服务器);
                }
                dbBackTrees.add(dbBackTree);
            }
            for (ServiceFile serviceFile : serviceFiles) {
                DbBackTree dbBackTree = new DbBackTree();
                dbBackTree.setId(serviceFile.getUuid());
                dbBackTree.setPId("0");
                dbBackTree.setTreeName(serviceFile.getServiceFileName());
                if(ServiceFileType.FASTDFS == serviceFile.getServiceFileType()){
                    dbBackTree.setTreeType(TreeType.ftp服务);
                }else{
                    dbBackTree.setTreeType(TreeType.fastdfs服务器);
                }
                dbBackTrees.add(dbBackTree);
            }
            return dbBackTrees;
        }
    }
}
